/*------------------------------------------------------------------------
|                            FILE DESCRIPTION                            |
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|  - File name     : os_task.h
|  - Author        : zeweni
|  - Update date   : 2021.03.25
|  - Copyright(C)  : 2021-2021 zeweni. All rights reserved.
------------------------------------------------------------------------*/
/*------------------------------------------------------------------------
|                            COPYRIGHT NOTICE                            |
------------------------------------------------------------------------*/
/*
 * Copyright (C) 2021, zeweni (17870070675@163.com)

 * This file is part of Ant Real Time Operating System.

 * Ant Real Time Operating System is free software: you can redistribute 
 * it and/or modify it under the terms of the Apache-2.0 License.

 * Ant Real Time Operating System is distributed in the hope that it will 
 * be useful,but WITHOUT ANY WARRANTY; without even the implied warranty 
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * Apache-2.0 License License for more details.

 * You should have received a copy of the Apache-2.0 License.Ant Real Time
 * Operating System. If not, see <http://www.apache.org/licenses/>.
**/
/*------------------------------------------------------------------------
|                                INCLUDES                                |
------------------------------------------------------------------------*/
#ifndef __OS_TASK_H_
#define __OS_TASK_H_

#include "os_type.h"
#include "os_object.h"

/*------------------------------------------------------------------------
|                                  MACRO                                 |
------------------------------------------------------------------------*/

/**
 * @brief     线程处于就绪态宏码。
 * @details   The thread is in the ready state macro code. 
**/
#define OS_THREAD_READY     0x00


/**
 * @brief     线程处于运行态宏码。
 * @details   The thread is in the running state macro code. 
**/
#define OS_THREAD_RUNNING   0x01


/**
 * @brief     线程处于休眠态宏码。
 * @details   The thread is in the sleep state macro code. 
**/
#define OS_THREAD_SLEEP     0x02


/**
 * @brief     线程处于阻塞态宏码。
 * @details   The thread is in the blocking state macro code. 
**/
#define OS_THREAD_BLOCK     0x03


/**
 * @brief     线程处于挂起态宏码。
 * @details   The thread is in the suspended state macro code. 
**/
#define OS_THREAD_SUSPEND   0x03


/**
 * @brief     线程自身宏码，作为对线程自身操作时的传参。
 * @details   The macro code of the thread itself is used 
 *            as a parameter for the operation of the thread itself.
**/
#define OS_THREAD_SELF    ((OS_Thread_t *) 0)


#if   (OS_SOFT_TIMER_CTRL == 0)

	/**
	 * @brief     线程链表长度宏，在原来基础上加1（空闲线程）。
	 * @details   The length of the thread list is macro, 
	 *            plus 1 (idle thread) on the original basis.
	**/
	#define    OS_THREAD_LIST_LEN  (OS_THREAD_MAX_NUM + 1)
	
#elif 

	/**
	 * @brief     线程链表长度宏，在原来基础上加2（空闲线程+软件定时器线程）。
	 * @details   The length of the thread list is macro, 
	 *            plus 1 (idle thread) on the original basis.
	**/
	#define    OS_THREAD_LIST_LEN  (OS_THREAD_MAX_NUM + 2)

#endif


/*------------------------------------------------------------------------
|                                  DATA                                  |
------------------------------------------------------------------------*/


/**
 * @brief     线程控制块结构体（对象）。
 * @details   Thread control block structure (object).
**/
struct OS_Thread
{
	struct OS_Object Parent;  /*!< 对象父类。Object parent class.. */
	void             *Entry;  /*!< 线程入口函数指针。Thread entry function pointer. */
	os_uint8_t         Prio;  /*!< 线程优先级。Thread priority. */
	os_uint16_t   TickSlice;  /*!< 线程运行时间片。The thread running time slice. */
	os_uint16_t      SliCtr;  /*!< 线程时间片计数器。The time slice counter of the thread. */	
	os_uint8_t       Status;  /*!< 线程运行状态。Thread running status. */
	os_uint16_t      SlpCtr;  /*!< 线程休眠计数器。Thread sleep counter. */
	OS_Thread_Stk  *StkAddr;  /*!< 线程堆栈地址。Thread stack address. */
	os_uint8_t      StkSize;  /*!< 线程堆栈大小。Thread stack size. */
};


/**
 * @brief     线程控制块结构体（对象）,指针类型。
 * @details   Thread control block structure (object), pointer type.
**/
typedef struct OS_Thread *OS_Thread_t;


typedef struct
{
    OS_Thread_t *pthrea;
	os_uint8_t thread_id; 
	void(*entry)(void *param);
	void *param;
	os_uint8_t priority;
	OS_Thread_Stk *stkAddr;
    OS_Thread_Stk **pstkAddr;
	os_uint8_t stkSize;
	os_uint16_t slice;
}OS_Thread_InitType;


/**
 * @brief   线程链表结构体。
 * @details Thread linked list structure.
**/
struct OS_Thread_List
{
	volatile void **Node[OS_THREAD_LIST_LEN];
	os_vuint8_t Num;
};

/**
 * @brief     线程队列结构体（对象）,指针类型。
 * @details   Thread queue structure (object), pointer type.
**/
typedef struct OS_Thread_List *OS_Thread_List_t;


/**
 * @brief   休眠任务链表结构体重定义。
 * @details The weight definition of the dormant task linked list structure.
**/
typedef void (* OS_Idle_Thread_Handle_t) (void);


/**
 * @brief    空闲函数入口句柄地址。
 * @details  RTOS idle task handle function.
**/
extern OS_Idle_Thread_Handle_t AntOS_Idle_Excute;


/**
 * @brief   正在运行的线程节点.
 * @details The thread node that is running.
**/
extern OS_Thread_t *G_OS_Thread_RunNode;

/**
 * @brief     线程就绪链表。
 * @details   Thread ready linked list.
**/
extern struct OS_Thread_List G_OS_Thread_RdyList;


/**
 * @brief     线程休眠链表队列。
 * @details   Thread sleep linked list queue.
**/
extern struct OS_Thread_List G_OS_Thread_SlpList;

/*------------------------------------------------------------------------
|                              API FUNCTIONS                             |
------------------------------------------------------------------------*/

/**
 * @brief     静态创建一个线程。成功则返回线程对象的句柄地址。
 * @details   Create a thread, and return the handle address of the thread object if it succeeds.
 * @param[in] thread     线程指针句柄，不可重复。Thread pointer handle, not repeatable.
 * @param[in] id          线程ID，不可重复。The ID of the thread, cannot be repeated.
 * @param[in] entry      线程入口地址。Thread entry address.
 * @param[in] param      线程入口参数。Thread entry parameters.
 * @param[in] priority   线程优先级。Thread priority
 * @param[in] stkAddr    线程堆栈地址。Thread stack address.
 * @param[in] stkSize    线程堆栈大小。Thread stack size.
 * @param[in] slice      线程运行时间片，单位是tick。Thread running time slice, the unit is tick.
 * @return    [OS_Thread_t]  线程初始化成功,返回线程句柄地址。
 *                           The thread is initialized successfully and the address is returned.
 * @return    [OS_NULL]      线程初始化失败。 The thread initialization failed.
 * @note      静态创建线程的方法，用户需要定义一个线程堆栈和线程控制块指针（可选），
 *            指针主要用来做线程控制，比如挂起和删除。
 *            To create a thread statically, 
 *            the user needs to define a thread stack and thread control block pointer (optional),
 *            The pointer is mainly used for thread control, such as suspend and delete.
**/
extern OS_Thread_t OS_Thread_Static_Create(OS_Thread_t *pthread,
										   os_uint8_t id, 
										   void(*entry)(void *param),
										   void *param,
										   os_uint8_t priority,
										   OS_Thread_Stk *stkAddr, 
										   os_uint8_t stkSize,
										   os_uint16_t slice);

/**
 * @brief     创建一个线程宏函数。成功则返回线程对象的句柄地址。
 * @details   Create a thread macro function statically, 
 *            and return the handle address of the thread object if it succeeds.
 * @param[in] thread     线程指针句柄，不可重复。Thread pointer handle, not repeatable.
 * @param[in] id         线程ID，不可重复。The ID of the thread, cannot be repeated.
 * @param[in] entry      线程入口地址。Thread entry address.
 * @param[in] param      线程入口参数。Thread entry parameters.
 * @param[in] priority   线程优先级。Thread priority
 * @param[in] stkAddr    线程堆栈地址。Thread stack address.
 * @param[in] stkSize    线程堆栈大小。Thread stack size.
 * @param[in] slice      线程运行时间片，单位是tick。Thread running time slice, the unit is tick.
**/
#define OS_CREATE_STATIC_THREAD(pthread,          \
								id,               \
								entry,            \
								param,            \
								priority,         \
								stkAddr,          \
								stkSize,          \
								slice)            \
do{                                               \
	pthread = OS_Thread_Static_Create(&pthread,   \
									id,           \
									entry,        \
									param,        \
									priority,     \
									stkAddr,      \
									stkSize,      \
									slice);       \
}while(0)


/**
 * @brief     动态创建一个线程。成功则返回线程对象的句柄地址。
 * @details   Create a thread, and return the handle address of the thread object if it succeeds.
 * @param[in] thread     线程指针句柄，不可重复。Thread pointer handle, not repeatable.
 * @param[in] thread_id  线程ID，不可重复。The ID of the thread, cannot be repeated.
 * @param[in] entry      线程入口地址。Thread entry address.
 * @param[in] param      线程入口参数。Thread entry parameters.
 * @param[in] priority   线程优先级。Thread priority
 * @param[in] stkAddr    线程堆栈地址。Thread stack address.
 * @param[in] stkSize    线程堆栈大小。Thread stack size.
 * @param[in] slice      线程运行时间片，单位是tick。Thread running time slice, the unit is tick.
 * @return    [OS_Thread_t]  线程初始化成功,返回线程句柄地址。
 *                           The thread is initialized successfully and the address is returned.
 * @return    [OS_NULL]      线程初始化失败。 The thread initialization failed.
 * @note      动态创建线程的方法，用户需要定义一个线程堆栈指针和线程控制块指针（可选），
 *            指针主要用来做线程控制，比如挂起和删除。
 *            To dynamically create threads, users need to define a thread stack pointer
 *            and thread control block pointer (optional),
 *            The pointer is mainly used for thread control, such as suspend and delete.
**/
extern OS_Thread_t OS_Thread_Create(OS_Thread_t *pthread,
									   os_uint8_t id, 
									   void(*entry)(void *param),
									   void *param,
									   os_uint8_t priority,
									   OS_Thread_Stk **stkAddr, 
									   os_uint8_t stkSize,
									   os_uint16_t slice);

/**
 * @brief     创建一个动态线程宏函数。成功则返回线程对象的句柄地址。
 * @details   Create a thread macro function statically, 
 *            and return the handle address of the thread object if it succeeds.
 * @param[in] thread     线程指针句柄，不可重复。Thread pointer handle, not repeatable.
 * @param[in] thread_id  线程ID，不可重复。The ID of the thread, cannot be repeated.
 * @param[in] entry      线程入口地址。Thread entry address.
 * @param[in] param      线程入口参数。Thread entry parameters.
 * @param[in] priority   线程优先级。Thread priority
 * @param[in] stkAddr    线程堆栈地址。Thread stack address.
 * @param[in] stkSize    线程堆栈大小。Thread stack size.
 * @param[in] slice      线程运行时间片，单位是tick。Thread running time slice, the unit is tick.
**/
#define OS_CREATE_THREAD(pthread,            \
						 thread_id,          \
						 entry,              \
						 param,              \
						 priority,           \
						 stkAddr,            \
						 stkSize,            \
						 slice)              \
do{                                          \
	pthread = OS_Thread_Create(&pthread,     \
							   thread_id,    \
							   entry,        \
							   param,        \
							   priority,     \
							   &stkAddr,     \
							   stkSize,      \
							   slice);       \
}while(0)
									   
/**
 * @brief     线程让出CPU使用权，并进入就绪态。
 * @details   The thread gives up the right to use the CPU and enters the ready state.
 * @param     None.
 * @return    [OS_OK]  线程让出成功。 Thread yields successfully.
 * @return    [OS_NOK] 线程让出失败。 Thread yield failure.
 * @note      如果被操作线程优先级在就绪队列中最高，将会被再次调度。
 *            If the priority of the operated thread is the highest in the ready queue, 
 *            it will be scheduled again.
**/
extern os_err_t OS_Thread_Yield(void);


/**
 * @brief     休眠一个线程（只能是自身），被休眠的线程主动让出CPU使用权。
 * @details   When a thread is hibernated, the hibernated thread voluntarily surrenders 
 *            the right to use the CPU.
 * @param[in] ticks 系统节拍数。The number of system beats.
 * @return    [OS_OK]  线程休眠成功。 The thread is sleep successfully.
 * @return    [OS_NOK] 线程休眠失败。 Thread sleep failure.
**/
extern os_err_t OS_Thread_Sleep(os_uint16_t ticks);


/**
 * @brief     删除一个静态线程，可以是自身，也可以是其他线程。
 * @details   Delete a process. This process can be itself or other threads.
 * @param[in] thread 要被删除的线程指针句柄地址。
 * @return    [OS_OK]  线程删除成功。 The thread is deleted successfully.
 * @return    [OS_NOK] 线程删除失败。 The thread delete failed.
 * @note      如果删除自身，那么将会触发一次任务调度。
 *            If you delete itself, it will trigger a task schedule.
 *            本API不能删除动态线程。This API cannot delete dynamic threads.
**/
extern os_err_t OS_Thread_Static_Delete(OS_Thread_t *thread);


/**
 * @brief     删除一个动态线程，可以是自身，也可以是其他线程。
 * @details   Delete a process. This process can be itself or other threads.
 * @param[in] thread  要被删除的线程指针句柄地址。
 * @param[in] stkAddr 要被删除的线程堆栈指针地址。
 * @return    [OS_OK]  线程删除成功。 The thread is deleted successfully.
 * @return    [OS_NOK] 线程删除失败。 The thread delete failed.
 * @note      如果删除自身，那么将会触发一次任务调度。
 *            If you delete itself, it will trigger a task schedule.
 *            本API不能删除静态线程。This API cannot delete static threads.
**/
extern os_err_t OS_Thread_Delete(OS_Thread_t *thread, OS_Thread_Stk **stkAddr);

/**
 * @brief     挂起一个线程，可以是自身，也可以是其他线程。
 * @details   Suspend a process. This process can be itself or other threads.
 * @param[in]     thread   要被挂起的线程。Thread to be suspended.
 * @return    [OS_OK]  线程挂起成功。 The thread is suspended successfully.
 * @return    [OS_NOK] 线程挂起失败。 The thread suspend failed.
 * @note      如果挂起自身，那么将会触发一次任务调度。
 *            If you suspend itself, it will trigger a task schedule
**/
extern os_err_t OS_Thread_Suspend(OS_Thread_t *thread);


/**
 * @brief     恢复一个线程，不可以是自身，只能是其他线程。
 * @details   Resume a process. This process can be itself or other threads.
 * @param[in] thread   要被恢复线程。Thread to be resumed.
 * @return    [OS_OK]  线程恢复成功。 The thread is resumeed successfully.
 * @return    [OS_NOK] 线程恢复失败。 The thread resume failed.
**/
extern os_err_t OS_Thread_Resume(OS_Thread_t *thread);


#endif
/*------------------------------------------------------------------------
|                    END OF FLIE.  (C) COPYRIGHT zeweni                  |
------------------------------------------------------------------------*/